package com.xwm.caffeine.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.benmanes.caffeine.cache.Cache;
import com.xwm.caffeine.constant.CacheConstant;
import com.xwm.caffeine.domain.Order;
import com.xwm.caffeine.mapper.OrderMapper;
import com.xwm.caffeine.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @Description: desc
 * @Author: xwm93up
 * @Since: 2022/4/13 16:19
 */
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    /*@Autowired
    private Cache cache;*/
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    @Cacheable(value = "order", key = "#id")
    public Order getOrderById(Long id) {
        String key = CacheConstant.ORDER + id;
        // V1
        /*Order order = (Order) cache.get(key,
                k -> {
                    //先查询 Redis
                    Object obj = redisTemplate.opsForValue().get(k);
                    if (Objects.nonNull(obj)) {
                        log.info("===========get data from redis============");
                        return obj;
                    }

                    // Redis没有则查询 DB
                    log.info("============get data from database============");
                    Order myOrder = orderMapper.selectOne(new LambdaQueryWrapper<Order>()
                            .eq(Order::getId, id));
                    redisTemplate.opsForValue().set(k, myOrder, 120, TimeUnit.SECONDS);
                    return myOrder;
                });
        return order;*/

        //V2
        //先查redis
        Object obj = redisTemplate.opsForValue().get(key);
        if (Objects.nonNull(obj)) {
            log.info("===========get data from redis============");
            return (Order) obj;
        }
        // Redis没有数据就查询DB
        // Redis没有则查询 DB
        log.info("============get data from database============");
        Order myOrder = orderMapper.selectOne(new LambdaQueryWrapper<Order>()
                .eq(Order::getId, id));
        redisTemplate.opsForValue().set(key, myOrder, 120, TimeUnit.SECONDS);
        return myOrder;
    }

    /**
     * V1版本
     * @param order
     */
    /*@Override
    public void updateOrder(Order order) {
        log.info("update order data");
        String key = CacheConstant.ORDER + order.getId();
        orderMapper.updateById(order);
        //修改 Redis
        redisTemplate.opsForValue().set(key, order, 120, TimeUnit.SECONDS);
        // 修改本地缓存
        cache.put(key, order);
    }*/

    /**
     * V2版本, 增加了返回值
     * @param order
     */
    @CachePut(cacheNames = "order", key = "#order.id")
    @Override
    public Order updateOrder(Order order) {
        log.info("update order data");
        String key = CacheConstant.ORDER + order.getId();
        orderMapper.updateById(order);
        //修改 Redis
        redisTemplate.opsForValue().set(key, order, 120, TimeUnit.SECONDS);
        return order;
    }

    @CacheEvict(cacheNames = "order", key = "#id")
    @Override
    public void deleteOrder(Long id) {
        log.info("delete order");
        orderMapper.deleteById(id);
        String key = CacheConstant.ORDER + id;
        redisTemplate.delete(key);
    }
}
